#region imported Namespaces
using System;
using System.Data;
using System.Data.SqlClient;

using BO = PHSRAG.Insight21.BusinessObjects;
using Utility = PHSRAG.Utility;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;
using GenerateKey = PHSRAG.Insight21.BusinessObjects.ModuleKey;
#endregion

namespace PHSRAG.Insight21.Agreements
{
	/// <summary>
	/// Summary description for AgreementProjectDetails.
	/// </summary>
	public class AgreementProjectDetails : BO.SaveableBusinessObject
	{
		#region Constants
		private static string AgreementProjectDetailsKey = GenerateKey.MakeKey("AgreementProjectDetails_F17FE574-C1D7-447c-A4FA-A1EFF311CAD6",GenerateKey.Agreement);
		private const string ProjectDetailsDataTableName = "ProjectDetails";
		#endregion

		#region Instance Variables
		private ICRate		 icRate1;
		private ICRate       icRate2;
		private Sponsor		 sponsor;
		private Fund		 fund;
		private Annotations  annotations;
        private string       requestedFundNumber;
		#endregion

		#region Public Properties
		/// <summary>
		/// Read only property containing Rex Folder Number. From AgrAgreement table.
		/// </summary>
		public string RexFolderNumber
		{
			get 
			{
				object o = DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["FolderNumber"];
				return (o == DBNull.Value) ? "" : (string)o;
			}
		}

		/// <summary>
		/// Sponsor Number is stored on the SvcEntity_AdmSponsor_Map table
		/// each agreement / sponsor combination has its own unique
		/// sponsor Number, so that's why it's stored and returned here
		/// instead of on the Sponsor itself, since a sponsor can have
		/// many agreements.
		/// </summary>
		public string SponsorNumber
		{
			get
			{
				object o = DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["SponsorNumber"];
				return (o == DBNull.Value) ? "" : (string)o;
			}
		}

		/// <summary>
		/// Facility Name, comes from a join to the 
		/// SvcEntity_AdmFacility_Map table.
		/// Currently this is read-only.
		/// </summary>
		public string FacilityName
		{
			get 
			{
				object o = DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["FacilityName"];
				return (o == DBNull.Value) ? "" : (string)o;
			}
		}

		/// <summary>
		/// Organization Name, comes from a join to the 
		/// SvcEntity_FwkDomainOrganization_Map table.
		/// Currently this is read-only.
		/// </summary>
		public string OrganizationName
		{
			get 
			{
				object o = DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["OrgName"];
				return (o == DBNull.Value) ? "" : (string)o;
			}
		}

		/// <summary>
		///  Read only FUnd ID
		/// </summary>
		public int FundId
		{
			get
			{
                if (RequestedFundNumber != null)
                {
                    return (int)DataContainer.Tables[ProjectDetailsDataTableName].Select(
                        string.Format("FundNumber = {0}", RequestedFundNumber))[0]["FundId"];
                }
                else
				    return (int)DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["FundId"];
			}
		}

		/// <summary>
		/// Id of the Agreement's Sponsor.
		/// </summary>
		public int SponsorId
		{
			get
			{	
				return (int)DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["AdmSponsorId"];
			}
		}

		public int BudgetContainerId
		{
			get
			{
				object o = DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["BudgetContainerId"];
				return (o == DBNull.Value) ? -1 : (int)o;
			}
		}

		public int AnnotationContainerId 
		{
			get
			{
				return (int)DataContainer.Tables[ProjectDetailsDataTableName].Rows[0]["AnnotationContainerId"];
			}
		}

		#region Public Contained Objects 

		/// <summary>
		/// Public readonly Sponsor object associated with this
		/// agreement.
		/// </summary>
		public Sponsor Sponsor
		{
			get
			{
				if ( sponsor == null )
				{
					sponsor = new Sponsor (CachePolicy);
					sponsor.Load( Utility.DataAccess.ConnectionString, SponsorId );
				}
				return sponsor;
			}
		}
		//sponsor

		/// <summary>
		/// Read only ICRate1 field from AgrBudgetICRate table, via
		/// AgrBudgetContainer table.
		/// </summary>
		public decimal ICRate1
		{
			get 
			{
				if ( icRate1 == null )
				{
					// ICRate Load expects 2 params ina ddition to Sql Conneciton
					// - the Id of it's container and the sequence Number.
					if ( BudgetContainerId == -1)
						return decimal.MinValue;

					icRate1= new ICRate(CachePolicy);
					icRate1.Load (Utility.DataAccess.ConnectionString, BudgetContainerId, 1);
				}
				return icRate1.Rate;
			}
		}

		/// <summary>
		/// Read only ICRate2 field from AgrBudgetICRate table, via
		/// AgrBudgetContainer table.
		/// </summary>
		public decimal ICRate2
		{
			get 
			{
				if ( icRate2 == null )
				{
					// ICRate Load expects 2 params ina ddition to Sql Conneciton
					// - the Id of it's container and the sequence Number.
					if ( BudgetContainerId == -1)
						return decimal.MinValue;

					icRate2= new ICRate(CachePolicy);
					icRate2.Load (Utility.DataAccess.ConnectionString, BudgetContainerId, 2);
				}
				return icRate2.Rate;
			}
		}

		/// <summary>
		/// Readonly Fund Object associated with an agreement, which is lazy-loaded.
		/// </summary>
		public Fund Fund
		{
			get
			{
				if( fund == null )
				{
					fund = new Fund(DataContainer, CachePolicy);
					fund.Load( Utility.DataAccess.ConnectionString, FundId);
				}
				return fund;
			}
		}

        /// <summary>
        /// Get/Set the requested fund number (for when an agreement has multiple funds).
        /// </summary>
        public string RequestedFundNumber
        {
            get
            {
                return requestedFundNumber;
            }
            set
            {
                requestedFundNumber = value;
            }
        }

		/// <summary>
		/// Collection of the annotations associated with an agreement.
		/// </summary>
		public Annotations Annotations
		{
			get 
			{
				if ( annotations == null )
				{		
					annotations = new Annotations(DataContainer, CachePolicy);
					annotations.Load( Utility.DataAccess.ConnectionString, AnnotationContainerId );
				}
				return annotations;
			}
			
		}
		#endregion

		#endregion

		#region Constructor

		public AgreementProjectDetails(DataSet dataSet, ICachePolicy cachePolicy) : base(cachePolicy)
		{
			DataContainer = dataSet;
		}
		
		#endregion

		#region Base Methods
		public override void Cache()
		{
			CachePolicy.Cache(AgreementProjectDetailsKey, this);
		}

		public override void UnCache()
		{
			CachePolicy.UnCache(AgreementProjectDetailsKey);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="connection"></param>
		/// <param name="agreementId"></param>
		public override void Load( string connectionString, params object[] args )
		{
			if ( args.Length != 1 )
			{
				throw new Exception ("Agreement Project Details Load expects Agreement ID." );
			}

			int agreementId = (int)args[0];

			try
			{
				Utility.DataAccess.LoadDataSet(DataContainer, ProjectDetailsDataTableName, connectionString,
					"GetAgreementProjectDetails", Utility.DataAccess.BuildSqlParameterArray("@agreementId" ,SqlDbType.Int, agreementId));
			}
			catch( Exception e)
			{
				Utility.ExceptionReport.WriteToEventLog ("Agreement Project Details Load", e, true, Utility.ExceptionReport.ReportType.Error);
			}
		}

		/// <summary>
		/// Saves the project detail's transactional members.
		/// </summary>
		/// <param name="connectionString">Sql Connection string info</param>
		public override void Save( string connectionString, params object[] args )
		{
			Annotations.Save( connectionString );
		}
		#endregion
	}
}
